package com.zt.bigdata.practise.time;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

/**
 * @ClassName UTCISOTime
 * @Description
 * @Author zhangtonghy
 * @Date 2019-02-15 09:18
 * @Copyright: 版权所有 (C) zt zt.
 * @注意：本内容仅限于zt内部传阅，禁止外泄以及用于其他的商业目的
 **/
public class UTCISOTime {

    public static void main(String[] args) {

        //T 也可以用空格表示，但是这两种表示有点不一样，
        // T 其实表示 UTC，而空格会被认为是本地时区（前提是不通过 Z 指定时区）
        String utcTime = "2018-05-23 16:05:52";
        String utcTimePatten = "yyyy-MM-dd HH:mm:ss";
        String localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();


        utcTime = "2018-05-23T16:05:52";
        utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss";
        localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();

        /*
        以上：
        不加时区，不管日期与时间之间是空格还是T都会被认为是GMT时区，
        而本地时区为东八区，所以最后转换的时间会在原基础上有8小时的偏移。
        2018-05-23T16:05:52  ==  2018-05-23T16:05:52.000+00:00是等价的。
        */

        //Z 用来表示传入时间的时区（zone），
        //不指定并且没有使用 T 分隔而是使用空格分隔时，就按GMT时区处理，比如下面的例子
        utcTime = "2018-05-23 16:05:52";
        utcTimePatten = "yyyy-MM-dd HH:mm:ss";
        localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();

        //因为指定时区GMT时区（偏移为 0），显示的时间会加上本地时区的偏移（8 小时）
        utcTime = "2018-05-23T16:05:52.000+00:00";
        utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
        localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();

        //东八区时间，显示的时间和传入的时间一致（因为我本地时区是东八区）。
        utcTime = "2018-05-23T16:05:52.000+08:00";
        utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
        localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();

        //将ISO8061格式的中的毫秒去掉，
        //yyyy-MM-dd'T'HH:mm:ss.SSSXXX格式中的.SSS就是表示毫秒的意思
        utcTime = "2018-05-23T16:05:52+08:00";
        utcTimePatten = "yyyy-MM-dd'T'HH:mm:ssXXX";
        localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();

        //yyyy-MM-dd'T'HH:mm:ss.SSSXXX格式中的XXX表示时区，
        // 一个X表示+08，三个X表示+08:00
        //一个X只读取了时区+08:30中的+08，而30却别忽略了
        utcTime = "2018-05-23T16:05:52+08:30";
        utcTimePatten = "yyyy-MM-dd'T'HH:mm:ssX";
        localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();

        //三个X，时间在原有的基础上又多了30分钟，
        // 所以XXX表示的是+08:30，而X只表示+08
        utcTime = "2018-05-23T16:05:52+08:30";
        utcTimePatten = "yyyy-MM-dd'T'HH:mm:ssXXX";
        localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();

        //2018-05-23T16:05:52.123Z时间格式
        //默认为GMT时区，显示的时间会加上本地时区的偏移（8 小时）
        utcTime = "2018-05-23T16:05:52.123Z";
        utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
        localTimePatten = "yyyy-MM-dd HH:mm:ss";
        System.out.println("UTC 时间: " + utcTime);
        System.out.println("本地 时间: " + utc2Local(utcTime, utcTimePatten, localTimePatten));
        System.out.println();
    }


    public static Date str2DateLong(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * 函数功能描述:UTC时间转本地时间格式
     *
     * @param utcTime           UTC时间
     * @param utcFormatString   UTC时间格式
     * @param localFormatString 本地时间格式
     * @return 本地时间格式的时间
     * eg:utc2Local("2017-06-14T09:37:50.788+08:00", "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", "yyyy-MM-dd HH:mm:ss.SSS")
     */
    public static String utc2Local(String utcTime, String utcFormatString, String localFormatString) {
        SimpleDateFormat utcFormat = new SimpleDateFormat(utcFormatString);
        //时区定义并进行时间获取
        utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date gpsUTCDate;
        try {
            gpsUTCDate = utcFormat.parse(utcTime);
        } catch (ParseException e) {
            e.printStackTrace();
            return utcTime;
        }
        SimpleDateFormat localFormat = new SimpleDateFormat(localFormatString);
        localFormat.setTimeZone(TimeZone.getDefault());
        String localTime = localFormat.format(gpsUTCDate.getTime());
        return localTime;
    }

}
